--[[
    Destructible Group
    可破坏物组
]]
local destructable = destructable

---@class mDestructibleGroup
local mDestructibleGroup = {
    type = 'module',
    module = 'dgroup',
    regList = {},

}
---@class cDestructibleGroup
---@field destructables destructable[]
local cDestructibleGroup = {
    type = 'class',
    class = 'dgroup',

}

local reg = destructable:event_any( '可破坏物-初始化', function (event, params)
    local unit = params.destructable
    mDestructibleGroup:reg( unit )
end)

local unReg = destructable:event_any( '可破坏物-死亡', function (event, params)
    local unit = params.destructable
    mDestructibleGroup:unReg( unit )
end)

---@private 注册进组
---@param d destructable
function mDestructibleGroup:reg(d)
    if self:reged(d) then return end
    local list = self.regList
    table_insert( list, d )
    list[ d ] = true
end

---@private 是否注册过
---@param d destructable
---@return bool
function mDestructibleGroup:reged(d)
    if self.regList[ d ] then
        return true
    end
    return false
end


---@private 取消注册
---@param d destructable
---@return bool
function mDestructibleGroup:unReg(d)
    if self:reged(d) then return end
    local list = self.regList
    for index, obj in ipairs(list) do
        if d == obj then
            list [  obj  ] = nil
            table.remove( list, index )
            list[0] = list[0] - 1
            return true
        end
    end
    return false
end


---@private 枚举所有注册过的对象
---@param callback fun( d:destructable ):bool 返回true 表示退出枚举
function mDestructibleGroup:enum( callback )
    local list = self.regList
    local i = 1
    local d = list[i]

    --暴力枚举直至nil
    while d do

        if callback( d ) then
            return
        end

        i = i + 1
        d = list[i]
    end

end

---@ 新建空组
---@return destructable
function mDestructibleGroup:new()
    ---@class dgroup : cDestructibleGroup
    local g = {
        type = 'dgroup',
        destructables = {},

    }
    setmetatable( g, cDestructibleGroup )
    return g
end

--- 添加可破坏物进入组
---@param u destructable
function cDestructibleGroup:addUnit( u )
    if self:isExist( u ) then
        return --已存在单位组内
    end
    table_insert( self.destructables, u )
    self.destructables [ u ] = true
end

--- 判断可破坏物是否在组中
---@param d destructable
---@return bool
function cDestructibleGroup:isExist( d )
    if self.destructables [ d ] then
        return true
    end
    return false
end

--- 从组中移除可破坏物
---@param d destructable
---@return bool
function cDestructibleGroup:removeUnit( d )
    if not self:isExist( d ) then
        return false--找不到该单位
    end
    local  list  =  self.destructables
    list[d] = nil
    for index, obj in ipairs(list) do
        if obj == d then
            table.remove( list, index )
            list[0] = list[0] - 1
            return true
        end
    end
    return true
end


--- 枚举所有注册过的可破坏物
---@param callback fun( d:destructable ):bool 返回true 表示退出枚举
function cDestructibleGroup:enum( callback )
    local list = self.destructables
    local i = 1
    local d = list[i]

    --暴力枚举直至nil
    while d do
        --已销毁
        if d.class ~= 'destructable' then
            table.remove( list, i )
            goto next
        end

        if callback( d ) then
            return
        end

        --被删除则不增加索引值
        if d == list[i] then
            i = i + 1
        end
        ::next::
        d = list[i]
    end

end

---@ 删除组
function cDestructibleGroup:del()
    self.destructables = nil
    setmetatable( self, nil )
end
